﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using System.Web;
using System.Xml;
using System.Threading;
using System.Data.OleDb;
using System.Net;
using System.Text.RegularExpressions;
using System.Reflection;
using System.CodeDom.Compiler;

namespace AliCMS.CollectModule.Bll
{
    public partial class Rule : DbObjectBase, IRule
    {
        public Rule(int instanceID, string lang, bool checkRight, string database)
            : base(instanceID, lang, checkRight, database)
        {
        }

        public override object ExecuteService(HttpContext context)
        {
            object result = null;

            string operation = context.Request.QueryString["Operation"];
            if (operation == "Add")
            {
                Dictionary<string, object> item = new Dictionary<string, object>();
                string value = null;
                value = context.Request.Form["ID"];
                if (value != null) item[Alias.Rule.ID] = value;
                value = context.Request.Form["Name"];
                if (value != null) item[Alias.Rule.Name + Lang] = value;
                value = context.Request.Form["Config"];
                if (value != null) item[Alias.Rule.Config] = value;
                value = context.Request.Form["Description"];
                if (value != null) item[Alias.Rule.Description + Lang] = value;
                value = context.Request.Form["Every"];
                if (value != null) item[Alias.Rule.Every] = value;
                value = context.Request.Form["StartTime"];
                if (value != null) item[Alias.Rule.StartTime] = value;
                value = context.Request.Form["AutoExport"];
                if (value != null) item[Alias.Rule.AutoExport] = value;
                value = context.Request.Form["LastRun"];
                if (value != null) item[Alias.Rule.LastRun] = value;
                value = context.Request.Form["RunTimes"];
                if (value != null) item[Alias.Rule.RunTimes] = value;
                value = context.Request.Form["EndTime"];
                if (value != null) item[Alias.Rule.EndTime] = value;
                value = context.Request.Form["LastID"];
                if (value != null) item[Alias.Rule.LastID] = value;
                value = context.Request.Form["UserAgent"];
                if (value != null) item[Alias.Rule.UserAgent] = value;
                value = context.Request.Form["IsDeleted"];
                if (value != null) item[Alias.Rule.IsDeleted] = value;
                value = context.Request.Form["Creator"];
                if (value != null) item[Alias.Rule.Creator] = value;
                value = context.Request.Form["CreatorID"];
                if (value != null) item[Alias.Rule.CreatorID] = value;
                value = context.Request.Form["CreateTime"];
                if (value != null) item[Alias.Rule.CreateTime] = value;
                value = context.Request.Form["Updator"];
                if (value != null) item[Alias.Rule.Updator] = value;
                value = context.Request.Form["UpdatorID"];
                if (value != null) item[Alias.Rule.UpdatorID] = value;
                value = context.Request.Form["UpdateTime"];
                if (value != null) item[Alias.Rule.UpdateTime] = value;

                result = Add(item);
            }
            else if (operation == "Modify")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);

                Dictionary<string, object> changes = new Dictionary<string, object>();
                string value = null;
                value = context.Request.Form["ID"];
                if (value != null) changes[Alias.Rule.ID] = value;
                value = context.Request.Form["Name"];
                if (value != null) changes[Alias.Rule.Name + Lang] = value;
                value = context.Request.Form["Config"];
                if (value != null) changes[Alias.Rule.Config] = value;
                value = context.Request.Form["Description"];
                if (value != null) changes[Alias.Rule.Description + Lang] = value;
                value = context.Request.Form["Every"];
                if (value != null) changes[Alias.Rule.Every] = value;
                value = context.Request.Form["StartTime"];
                if (value != null) changes[Alias.Rule.StartTime] = value;
                value = context.Request.Form["AutoExport"];
                if (value != null) changes[Alias.Rule.AutoExport] = value;
                value = context.Request.Form["LastRun"];
                if (value != null) changes[Alias.Rule.LastRun] = value;
                value = context.Request.Form["RunTimes"];
                if (value != null) changes[Alias.Rule.RunTimes] = value;
                value = context.Request.Form["EndTime"];
                if (value != null) changes[Alias.Rule.EndTime] = value;
                value = context.Request.Form["LastID"];
                if (value != null) changes[Alias.Rule.LastID] = value;
                value = context.Request.Form["UserAgent"];
                if (value != null) changes[Alias.Rule.UserAgent] = value;
                value = context.Request.Form["IsDeleted"];
                if (value != null) changes[Alias.Rule.IsDeleted] = value;
                value = context.Request.Form["Creator"];
                if (value != null) changes[Alias.Rule.Creator] = value;
                value = context.Request.Form["CreatorID"];
                if (value != null) changes[Alias.Rule.CreatorID] = value;
                value = context.Request.Form["CreateTime"];
                if (value != null) changes[Alias.Rule.CreateTime] = value;
                value = context.Request.Form["Updator"];
                if (value != null) changes[Alias.Rule.Updator] = value;
                value = context.Request.Form["UpdatorID"];
                if (value != null) changes[Alias.Rule.UpdatorID] = value;
                value = context.Request.Form["UpdateTime"];
                if (value != null) changes[Alias.Rule.UpdateTime] = value;

                Modify(id, changes);
            }
            else if (operation == "GetInnerIDFromGuid")
            {
                Guid guid = new Guid(context.Request.QueryString["ID"]);
                result = GetInnerIDFromGuid(guid);
            }
            else if (operation == "GetGuidFromInnerID")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);
                result = GetGuidFromInnerID(id);
            }
            else if (operation == "Recycle")
            {
                string id = context.Request.QueryString["ID"];

                string[] ids = id.Split('|');
                for (int i = 0; i < ids.Length; i++)
                {
                    if (String.IsNullOrEmpty(ids[i]))
                        continue;

                    Recycle(Convert.ToInt32(ids[i]));
                }
            }
            else if (operation == "Recover")
            {
                string id = context.Request.QueryString["ID"];

                string[] ids = id.Split('|');
                for (int i = 0; i < ids.Length; i++)
                {
                    if (String.IsNullOrEmpty(ids[i]))
                        continue;

                    Recover(Convert.ToInt32(ids[i]));
                }
            }
            else if (operation == "Delete")
            {
                string id = context.Request.QueryString["ID"];

                string[] ids = id.Split('|');
                for (int i = 0; i < ids.Length; i++)
                {
                    if (String.IsNullOrEmpty(ids[i]))
                        continue;

                    if (i > 0)
                    {
                        Dal.EndWork();
                        Dal.BeginWork(InstanceID, Lang, CheckRight, String.Empty);
                    }

                    Delete(Convert.ToInt32(ids[i]));
                }
            }
            else if (operation == "List")
            {
                string value = null;

                int page = -1;
                value = context.Request.QueryString["Page"];
                if (value != null) page = Convert.ToInt32(value);

                int pageSize = -1;
                value = context.Request.QueryString["PageSize"];
                if (value != null) pageSize = Convert.ToInt32(value);

                string condition = context.Request.QueryString["Condition"];
                string sort = context.Request.QueryString["Sort"];

                result = List(page, pageSize, condition, sort);
            }
            else if (operation == "StartExecute")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);
                StartExecute(id);
            }
            else if (operation == "StopExecute")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);
                StopExecute(id);
            }
            else if (operation == "IsRunning")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);
                result = IsRunning(id);
            }
            /*
            else if (operation == "SetExport")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);
                string export = context.Request.Form["Export"];
                SetExport(id, export);
            }
            */
            else if (operation == "Export")
            {
                int id = Convert.ToInt32(context.Request.QueryString["ID"]);
                int recordID = Convert.ToInt32(context.Request.QueryString["RecordID"]);
                Export(id, recordID);
            }
            else
            {
                throw new Exception("lang_header_param");
            }

            return result;
        }

        public int GetInnerIDFromGuid(Guid guid)
        {
            return Dal.GetInnerIDFromGuid(guid);
        }
        public Guid GetGuidFromInnerID(object id)
        {
            return Dal.GetGuidFromInnerID(id);
        }
        public Dictionary<string, object> Get(object id)
        {
            if (CheckRight)
            {
                Guid guid;
                if (id is Guid)
                    guid = (Guid)id;
                else
                    guid = Dal.GetGuidFromInnerID(id);
                ValidateRight("Get", guid);
            }

            return Dal.Get(id);
        }
        public Guid Add(Dictionary<string, object> item)
        {
            if (CheckRight)
            {
                ValidateRight("Add", Guid.Empty);
            }

            if (!item.ContainsKey(Alias.Rule.ID) || item[Alias.Rule.ID].ToString() == String.Empty)
                item[Alias.Rule.ID] = Guid.NewGuid();
            else if (!(item[Alias.Rule.ID] is Guid))
                item[Alias.Rule.ID] = new Guid(item[Alias.Rule.ID].ToString());

            if (item.ContainsKey(Alias.Rule.Every))
            {
                string every = Convert.ToString(item[Alias.Rule.Every]);
                if (String.IsNullOrEmpty(every))
                    item[Alias.Rule.Every] = DBNull.Value;
            }

            if (item.ContainsKey(Alias.Rule.StartTime))
            {
                string startTime = item[Alias.Rule.StartTime].ToString();
                if (startTime == String.Empty)
                    item[Alias.Rule.StartTime] = DBNull.Value;
                else
                    item[Alias.Rule.StartTime] = Convert.ToDateTime(startTime);
            }

            if (item.ContainsKey(Alias.Rule.EndTime))
            {
                string endTime = item[Alias.Rule.EndTime].ToString();
                if (endTime == String.Empty)
                    item[Alias.Rule.EndTime] = DBNull.Value;
                else
                    item[Alias.Rule.EndTime] = Convert.ToDateTime(endTime);
            }

            if (item.ContainsKey(Alias.Rule.LastID))
            {
                string lastID = Convert.ToString(item[Alias.Rule.LastID]);
                if (String.IsNullOrEmpty(lastID))
                    item[Alias.Rule.LastID] = DBNull.Value;
            }

            if (item.ContainsKey(Alias.Rule.CreatorID) && !String.IsNullOrEmpty(Convert.ToString(item[Alias.Rule.CreatorID])))
            {
                item[Alias.Rule.CreatorID] = new Guid(item[Alias.Rule.CreatorID].ToString());
            }
            else
            {
                Dictionary<string, string> user = Manager.User;
                if (user != null)
                {
                    item[Alias.Rule.Creator] = user["Name"];
                    item[Alias.Rule.CreatorID] = new Guid(user["ID"]);
                }
            }

            if (item.ContainsKey(Alias.Rule.CreateTime))
                item[Alias.Rule.CreateTime] = Convert.ToDateTime(item[Alias.Rule.CreateTime]);
            else
                item[Alias.Rule.CreateTime] = DateTime.Now;

            if (item.ContainsKey(Alias.Rule.UpdateTime))
                item[Alias.Rule.UpdateTime] = Convert.ToDateTime(item[Alias.Rule.UpdateTime]);
            else
                item[Alias.Rule.UpdateTime] = DateTime.Now;

            Dal.Add(item);

            #region 定时和定期规则时，设置系统任务
            if (item.ContainsKey(Alias.Rule.Every) && !Convert.IsDBNull(item[Alias.Rule.Every]))
            {
                using (SystemModule.ITask taskBll = (SystemModule.ITask)Manager.CreateObject("Task", 0, Lang, false))
                {
                    DataRow instance = Manager.Instances.Select(SystemModule.Alias.Instance.InnerID + "=" + InstanceID)[0];

                    Dictionary<string, object> task = new Dictionary<string, object>();
                    task[SystemModule.Alias.Task.Name] = item[Alias.Rule.Name + Lang];
                    task[SystemModule.Alias.Task.InstanceID] = instance[SystemModule.Alias.Instance.ID];
                    task[SystemModule.Alias.Task.Object] = "Rule";
                    task[SystemModule.Alias.Task.Lang] = Lang;
                    task[SystemModule.Alias.Task.Operation] = "StartExecute";
                    task[SystemModule.Alias.Task.Record] = item[Alias.Rule.ID].ToString();
                    task[SystemModule.Alias.Task.Every] = item[Alias.Rule.Every];
                    task[SystemModule.Alias.Task.StartTime] = item[Alias.Rule.StartTime];

                    taskBll.Add(task);
                }

                Manager.UpdateTask();
            }
            #endregion

            return (Guid)item[Alias.Rule.ID];
        }
        public void Modify(int id, Dictionary<string, object> changes)
        {
            if (CheckRight)
            {
                Guid guid = Dal.GetGuidFromInnerID(id);
                ValidateRight("Modify", guid);
            }

            if (changes.ContainsKey(Alias.Rule.ID) && !(changes[Alias.Rule.ID] is Guid))
                changes[Alias.Rule.ID] = new Guid(changes[Alias.Rule.ID].ToString());

            if (changes.ContainsKey(Alias.Rule.Every))
            {
                string every = Convert.ToString(changes[Alias.Rule.Every]);
                if (String.IsNullOrEmpty(every))
                    changes[Alias.Rule.Every] = DBNull.Value;
            }

            if (changes.ContainsKey(Alias.Rule.StartTime))
            {
                string startTime = changes[Alias.Rule.StartTime].ToString();
                if (startTime == String.Empty)
                    changes[Alias.Rule.StartTime] = DBNull.Value;
                else
                    changes[Alias.Rule.StartTime] = Convert.ToDateTime(startTime);
            }

            if (changes.ContainsKey(Alias.Rule.EndTime))
            {
                string endTime = changes[Alias.Rule.EndTime].ToString();
                if (endTime == String.Empty)
                    changes[Alias.Rule.EndTime] = DBNull.Value;
                else
                    changes[Alias.Rule.EndTime] = Convert.ToDateTime(endTime);
            }

            if (changes.ContainsKey(Alias.Rule.LastID))
            {
                string lastID = Convert.ToString(changes[Alias.Rule.LastID]);
                if (String.IsNullOrEmpty(lastID))
                    changes[Alias.Rule.LastID] = DBNull.Value;
            }

            if (changes.ContainsKey(Alias.Rule.UpdatorID))
            {
                changes[Alias.Rule.UpdatorID] = new Guid(changes[Alias.Rule.UpdatorID].ToString());
            }
            else
            {
                Dictionary<string, string> user = Manager.User;
                if (user != null)
                {
                    changes[Alias.Rule.Updator] = user["Name"];
                    changes[Alias.Rule.UpdatorID] = new Guid(user["ID"]);
                }
            }

            if (changes.ContainsKey(Alias.Rule.UpdateTime))
                changes[Alias.Rule.UpdateTime] = Convert.ToDateTime(changes[Alias.Rule.UpdateTime]);

            Dal.Modify(id, changes);

            #region 定时和定期规则时，设置系统任务
            Dictionary<string, object> item = Dal.Get(id);
            if (item.ContainsKey(Alias.Rule.Every) && changes.ContainsKey(Alias.Rule.StartTime) && !Convert.ToBoolean(item[Alias.Rule.IsDeleted]))
            {
                using (SystemModule.ITask taskBll = (SystemModule.ITask)Manager.CreateObject("Task", 0, Lang, false))
                {
                    DataRow instance = Manager.Instances.Select(SystemModule.Alias.Instance.InnerID + "=" + InstanceID)[0];

                    StringBuilder condition = new StringBuilder();
                    condition.Append(SystemModule.Alias.Task.InstanceID + "=" + instance[SystemModule.Alias.Instance.ID]);
                    condition.Append(" AND " + SystemModule.Alias.Task.Object + "='Rule'");
                    condition.Append(" AND " + SystemModule.Alias.Task.Operation + "='StartExecute'");
                    condition.Append(" AND (" + SystemModule.Alias.Task.Record + "='" + id + "' OR " + SystemModule.Alias.Task.Record + "='" + item[Alias.Rule.ID] + "')");
                    DataTable table = taskBll.List(-1, -1, condition.ToString(), null);
                    foreach (DataRow row in table.Rows)
                    {
                        taskBll.Delete((int)row[SystemModule.Alias.Task.InnerID]);
                    }

                    if (!Convert.IsDBNull(item[Alias.Rule.Every]))
                    {
                        Dictionary<string, object> task = new Dictionary<string, object>();
                        task[SystemModule.Alias.Task.Name] = item[Alias.Rule.Name];
                        task[SystemModule.Alias.Task.InstanceID] = instance[SystemModule.Alias.Instance.ID];
                        task[SystemModule.Alias.Task.Object] = "Rule";
                        task[SystemModule.Alias.Task.Lang] = Lang;
                        task[SystemModule.Alias.Task.Operation] = "StartExecute";
                        task[SystemModule.Alias.Task.Record] = item[Alias.Rule.ID].ToString();
                        task[SystemModule.Alias.Task.Every] = item[Alias.Rule.Every];
                        task[SystemModule.Alias.Task.StartTime] = item[Alias.Rule.StartTime];

                        taskBll.Add(task);
                    }
                }

                Manager.UpdateTask();
            }
            #endregion
        }
        public void Recycle(int id)
        {
            if (CheckRight)
            {
                Guid guid = Dal.GetGuidFromInnerID(id);
                ValidateRight("Recycle", guid);
            }

            Dictionary<string, object> changes = new Dictionary<string, object>();
            changes[Alias.Rule.IsDeleted] = true;

            Dal.Modify(id, changes);

            #region 定时和定期规则时，设置系统任务
            Dictionary<string, object> item = Dal.Get(id);
            if (item.ContainsKey(Alias.Rule.Every) && !Convert.IsDBNull(item[Alias.Rule.Every]))
            {
                using (SystemModule.ITask taskBll = (SystemModule.ITask)Manager.CreateObject("Task", 0, Lang, false))
                {
                    DataRow instance = Manager.Instances.Select(SystemModule.Alias.Instance.InnerID + "=" + InstanceID)[0];

                    StringBuilder condition = new StringBuilder();
                    condition.Append(SystemModule.Alias.Task.InstanceID + "=" + instance[SystemModule.Alias.Instance.ID]);
                    condition.Append(" AND " + SystemModule.Alias.Task.Object + "='Rule'");
                    condition.Append(" AND " + SystemModule.Alias.Task.Operation + "='StartExecute'");
                    condition.Append(" AND (" + SystemModule.Alias.Task.Record + "='" + id + "' OR " + SystemModule.Alias.Task.Record + "=" + item[Alias.Rule.ID] + ")");
                    DataTable table = taskBll.List(-1, -1, condition.ToString(), null);
                    foreach (DataRow row in table.Rows)
                    {
                        taskBll.Delete((int)row[SystemModule.Alias.Task.InnerID]);
                    }
                }

                Manager.UpdateTask();
            }
            #endregion
        }
        public void Recover(int id)
        {
            if (CheckRight)
            {
                Guid guid = Dal.GetGuidFromInnerID(id);
                ValidateRight("Recover", guid);
            }

            Dictionary<string, object> changes = new Dictionary<string, object>();
            changes[Alias.Rule.IsDeleted] = false;

            Dal.Modify(id, changes);

            #region 定时和定期规则时，设置系统任务
            Dictionary<string, object> item = Dal.Get(id);
            if (item.ContainsKey(Alias.Rule.Every) && !Convert.IsDBNull(item[Alias.Rule.Every]))
            {
                using (SystemModule.ITask taskBll = (SystemModule.ITask)Manager.CreateObject("Task", 0, Lang, false))
                {
                    DataRow instance = Manager.Instances.Select(SystemModule.Alias.Instance.InnerID + "=" + InstanceID)[0];

                    Dictionary<string, object> task = new Dictionary<string, object>();
                    task[SystemModule.Alias.Task.Name] = item[Alias.Rule.Name];
                    task[SystemModule.Alias.Task.InstanceID] = instance[SystemModule.Alias.Instance.ID];
                    task[SystemModule.Alias.Task.Object] = "Rule";
                    task[SystemModule.Alias.Task.Lang] = Lang;
                    task[SystemModule.Alias.Task.Operation] = "StartExecute";
                    task[SystemModule.Alias.Task.Record] = item[Alias.Rule.ID].ToString();
                    task[SystemModule.Alias.Task.Every] = item[Alias.Rule.Every];
                    task[SystemModule.Alias.Task.StartTime] = item[Alias.Rule.StartTime];

                    taskBll.Add(task);
                }

                Manager.UpdateTask();
            }
            #endregion
        }
        public void Delete(int id)
        {
            if (CheckRight)
            {
                Guid guid = Dal.GetGuidFromInnerID(id);
                ValidateRight("Delete", guid);
            }

            Dictionary<string, object> item = Dal.Get(id);

            Dal.Delete(id);

            #region 删除相关目录
            string path = Manager.MapPath(Manager.GetDataPath(InstanceID, null) + "file/" + item[Alias.Rule.ID] + "/");
            if (Directory.Exists(path))
                Manager.DeleteFolder(path, true);
            #endregion

            #region 定时和定期规则时，设置系统任务
            if (item.ContainsKey(Alias.Rule.Every) && !Convert.IsDBNull(item[Alias.Rule.Every]))
            {
                using (SystemModule.ITask taskBll = (SystemModule.ITask)Manager.CreateObject("Task", 0, Lang, false))
                {
                    DataRow instance = Manager.Instances.Select(SystemModule.Alias.Instance.InnerID + "=" + InstanceID)[0];

                    StringBuilder condition = new StringBuilder();
                    condition.Append(SystemModule.Alias.Task.InstanceID + "=" + instance[SystemModule.Alias.Instance.ID]);
                    condition.Append(" AND " + SystemModule.Alias.Task.Object + "='Rule'");
                    condition.Append(" AND " + SystemModule.Alias.Task.Operation + "='StartExecute'");
                    condition.Append(" AND (" + SystemModule.Alias.Task.Record + "='" + id + "' OR " + SystemModule.Alias.Task.Record + "=" + item[Alias.Rule.ID] + ")");
                    DataTable table = taskBll.List(-1, -1, condition.ToString(), null);
                    foreach (DataRow row in table.Rows)
                    {
                        taskBll.Delete((int)row[SystemModule.Alias.Task.InnerID]);
                    }
                }

                Manager.UpdateTask();
            }
            #endregion
        }
        public DataTable List(int page, int pageSize, string condition, string sort)
        {
            if (CheckRight)
            {
                ValidateRight("List", Guid.Empty);
            }

            return Dal.List(page, pageSize, condition, sort);
        }
        public int GetRecordCount(string condition)
        {
            return Dal.GetRecordCount(condition);
        }

        /*
        public void SetExport(int id, string export)
        {
            if (CheckRight)
            {
                Guid guid = Dal.GetGuidFromInnerID(id);
                ValidateRight("SetExport", guid);
            }

            Dictionary<string, object> rule = Dal.Get(id);

            Dictionary<string, object> changes = new Dictionary<string, object>();
            string config = rule[Alias.Rule.Config].ToString();
            if (config == "")
            {
                changes[Alias.Rule.Config] = "<Rule>" + export + "</Rule>";
            }
            else
            {
                config = Regex.Replace(config, @"<Export[^<]*>(.|\s)*?</Export>", "", RegexOptions.IgnoreCase);
                int index = config.LastIndexOf("</Rule>");
                config = config.Insert(index, export);
                changes[Alias.Rule.Config] = config;
            }
            Dal.Modify(id, changes);
        }
        */
        public void Export(int id, int recordID)
        {
            HttpContext.Current.Server.ScriptTimeout = 24 * 60 * 60;

            if (_manager == null)
                _manager = Manager;
            else
                Manager = _manager;

            Dictionary<string, object> rule = Dal.Get(id);

            #region 获取栏目配置
            Dictionary<string, string> instanceConfig = null;
            using (IInstanceConfig configBll = (IInstanceConfig)_manager.CreateObject("InstanceConfig", InstanceID, Lang, false))
            {
                instanceConfig = configBll.GetBasicSettings();
            }
            #endregion

            #region 检查数据库是否存在
            string db = null;
            string connectionString = instanceConfig[Alias.InstanceConfig.ConnectionString];
            connectionString = connectionString.Replace("{#InstancePath#}", _manager.MapPath(_manager.GetDataPath(InstanceID, null)));
            connectionString = connectionString.Replace("{#WebPath#}", _manager.MapPath(_manager.GetWebPath()));
            connectionString = connectionString.Replace("{#DataPath#}", _manager.MapPath(_manager.GetDataPath(null, null)));
            string[] parts = connectionString.Split(';');
            foreach (string part in parts)
            {
                string[] pair = part.Split('=');
                if (pair[0] == "Data Source")
                {
                    db = pair[1];
                    break;
                }
            }
            if (db == null || !File.Exists(db))
                return;
            #endregion

            ExportClass export = new ExportClass();
            if (export.Open(rule, connectionString, Lang, null))
            {
                export.Execute(recordID, 0, Guid.Empty);
                export.Close();
            }
        }
        private class ExportClass : IDisposable
        {
            ~ExportClass()
            {
                Dispose();
            }
            public void Dispose()
            {
                Close();
                GC.SuppressFinalize(this);
            }

            public bool Open(Dictionary<string, object> rule, string connectionString, string lang, XmlNode exportNode)
            {
                _rule = rule;
                _connectionString = connectionString;
                _lang = lang;

                #region 获取规则配置
                if (_rule[Alias.Rule.Config].ToString() == String.Empty)
                    return false;

                _config = new XmlDocument();
                _config.LoadXml(_rule[Alias.Rule.Config].ToString());

                if (exportNode == null)
                {
                    _fieldNodes = _config.DocumentElement.SelectNodes("Fields/Field");
                }
                else
                {
                    XmlNode subRule = _config.DocumentElement.SelectSingleNode("//Rule[@Name='" + exportNode.Attributes["Name"].Value + "']");
                    _fieldNodes = subRule.SelectNodes("Fields/Field");
                }
                if (_fieldNodes.Count == 0)
                    return false;

                if (exportNode == null)
                    _exportNode = _config.DocumentElement.SelectSingleNode("Export");
                else
                    _exportNode = exportNode;
                if (_exportNode == null)
                    return false;

                _fieldNodes = _exportNode.SelectNodes("Fields/Field");
                if (_fieldNodes.Count == 0)
                    return false;
                #endregion

                #region 获取目标栏目，对象和属性
                DataRow[] rows = null;
                if (_exportNode.Attributes["Instance"] != null && _exportNode.Attributes["Instance"].Value != String.Empty)
                    rows = _manager.Instances.Select(SystemModule.Alias.Instance.ID + "='" + _exportNode.Attributes["Instance"].Value + "'");
                if (rows == null || rows.Length == 0)
                {
                    if (_exportNode.Attributes["Module"] != null)
                        rows = _manager.Instances.Select(SystemModule.Alias.Module.Namespace + "='" + _exportNode.Attributes["Module"].Value + "'");
                    else if (exportNode != null)
                        rows = _manager.Instances.Select(SystemModule.Alias.Module.Namespace + "='" + _exportNode.ParentNode.Attributes["Module"].Value + "'");
                }
                if (rows == null || rows.Length == 0)
                    return false;
                DataRow instance = rows[0];

                rows = _manager.Objects.Select(SystemModule.Alias.Module.Object.Namespace + "='" + instance[SystemModule.Alias.Module.Namespace] + "' and FullName='" + _exportNode.Attributes["Object"].Value + "'");
                if (rows.Length == 0)
                    return false;

                _properties = _manager.Properties.Select(SystemModule.Alias.Module.Object.Property.ObjectID + "='" + rows[0][SystemModule.Alias.Module.Object.ID] + "'");

                _tobll = (IDbObject)_manager.CreateObject(_exportNode.Attributes["Object"].Value, (int)instance[SystemModule.Alias.Instance.InnerID], _lang, false);
                #endregion

                #region 准备（1）必填，但没有默认值的，也没在导出映射里。（2）唯一，也没在导出映射里。
                _extra = new Dictionary<string, OleDbType>();
                foreach (DataRow property in _properties)
                {
                    if (Convert.ToBoolean(property[SystemModule.Alias.Module.Object.Property.PrimaryKey]) ||
                        Convert.ToBoolean(property[SystemModule.Alias.Module.Object.Property.IsIdentity]) ||
                        property[SystemModule.Alias.Module.Object.Property.OleDbDefault].ToString().Length > 0)
                        continue;

                    bool exist = false;
                    foreach (XmlNode fieldNode in _fieldNodes)
                    {
                        if (property[SystemModule.Alias.Module.Object.Property.Name].ToString() == fieldNode.Attributes["To"].Value)
                        {
                            exist = true;
                            break;
                        }
                    }
                    if (exist)
                        continue;

                    if (Convert.ToBoolean(property[SystemModule.Alias.Module.Object.Property.Unique]) || !Convert.ToBoolean(property[SystemModule.Alias.Module.Object.Property.IsNullable]))
                    {
                        _extra[property[SystemModule.Alias.Module.Object.Property.UniqueInnerID].ToString()] = (OleDbType)Convert.ToByte(property[SystemModule.Alias.Module.Object.Property.OleDbType]);
                    }
                }
                #endregion

                #region 打开数据库
                _connection = new OleDbConnection(connectionString);
                _command = new OleDbCommand();
                _command.Connection = _connection;
                _connection.Open();
                #endregion

                return true;
            }
            public void Execute(int id, int parentID, Guid targetParentID)
            {
                Dictionary<string, object> items = new Dictionary<string, object>();
                StringBuilder stopCondition = new StringBuilder();
                StringBuilder unique = new StringBuilder();

                string tableName = null;
                if (_exportNode.Attributes["Name"] == null)
                    tableName = _config.DocumentElement.Attributes["Name"].Value;
                else
                    tableName = _exportNode.Attributes["Name"].Value;

                _command.Parameters.Clear();
                if (id == 0)
                {
                    _command.Parameters.Add("@RuleID", OleDbType.Guid).Value = _rule[Alias.Rule.ID];
                    _command.CommandText = "SELECT * FROM [" + tableName + "] WHERE [RuleID]=?" + (parentID > 0 ? " AND [ParentID]=" + parentID : "") + " ORDER BY [ID] ASC";
                }
                else
                {
                    _command.Parameters.Add("@ID", OleDbType.Integer).Value = id;
                    _command.CommandText = "SELECT TOP 1 * FROM [" + tableName + "] WHERE [ID]=?";
                }

                _reader = _command.ExecuteReader();
                while (_reader.Read())
                {
                    try
                    {
                        string guidField = null;
                        string innerIDField = null;

                        #region On条件
                        string action = null;
                        XmlNodeList ons = _exportNode.SelectNodes("Ons/On[@From]");
                        foreach (XmlNode on in ons)
                        {
                            if (on.Attributes["Value"] == null)
                                continue;

                            string value = on.Attributes["Value"].Value;
                            if (value.StartsWith("/") && value.EndsWith("/"))
                            {
                                if (!Regex.IsMatch(_reader[on.Attributes["From"].Value].ToString(), value.Substring(1, value.Length - 2), RegexOptions.IgnoreCase))
                                    continue;
                            }
                            else
                            {
                                if (_reader[on.Attributes["From"].Value].ToString() != value)
                                    continue;
                            }

                            if (on.Attributes["Action"] != null && on.Attributes["Action"].Value == "Stop")
                                action = "Stop";
                            else
                                action = "Continue";
                            break;
                        }

                        if (action == "Stop")
                            break;
                        if (action == "Continue")
                            continue;
                        #endregion

                        #region 准备Items（添加项），唯一条件和停止条件
                        items.Clear();
                        stopCondition.Remove(0, stopCondition.Length);
                        unique.Remove(0, unique.Length);
                        foreach (XmlNode fieldNode in _fieldNodes)
                        {
                            foreach (DataRow property in _properties)
                            {
                                if (property[SystemModule.Alias.Module.Object.Property.Name].ToString() == "ID")
                                    guidField = property[SystemModule.Alias.Module.Object.Property.UniqueInnerID].ToString();

                                if (property[SystemModule.Alias.Module.Object.Property.Name].ToString() == "InnerID")
                                    innerIDField = property[SystemModule.Alias.Module.Object.Property.UniqueInnerID].ToString();

                                if (property[SystemModule.Alias.Module.Object.Property.Name].ToString() == fieldNode.Attributes["To"].Value)
                                {
                                    object value = _reader[fieldNode.Attributes["From"].Value];

                                    string lang = null;
                                    if (Convert.ToBoolean(property[SystemModule.Alias.Module.Object.Property.MultiLanguage]) && !String.IsNullOrEmpty(_lang))
                                        lang = _lang;

                                    #region 处理外键
                                    if (fieldNode.Attributes["From"].Value == "ParentID")
                                    {
                                        items[property[SystemModule.Alias.Module.Object.Property.UniqueInnerID].ToString()] = targetParentID;
                                        continue;
                                    }
                                    #endregion

                                    #region 处理“值映射”
                                    bool isMap = false;
                                    XmlNodeList maps = fieldNode.SelectNodes("Value");
                                    foreach (XmlNode map in maps)
                                    {
                                        if (map.Attributes["From"] == null && map.Attributes["To"] == null)
                                            continue;

                                        if (map.Attributes["From"] == null || map.Attributes["From"].Value == String.Empty || map.Attributes["From"].Value == value.ToString())
                                        {
                                            items[property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + lang] = map.Attributes["To"].Value;
                                            isMap = true;
                                            break;
                                        }
                                    }

                                    if (isMap)
                                        continue;
                                    #endregion

                                    XmlNode stopNode = _exportNode.SelectSingleNode("Stop/Condition[@Field='" + fieldNode.Attributes["From"].Value + "']");

                                    OleDbType dbtype = (OleDbType)Convert.ToByte(property[SystemModule.Alias.Module.Object.Property.OleDbType]);
                                    if (dbtype == OleDbType.VarChar || dbtype == OleDbType.VarWChar)
                                    {
                                        int size = Convert.ToInt32(property[SystemModule.Alias.Module.Object.Property.MaxLength]);
                                        if (value.ToString().Length > size)
                                            value = value.ToString().Substring(0, size);

                                        if (stopNode != null)
                                        {
                                            if (stopCondition.Length != 0)
                                                stopCondition.Append(" OR ");

                                            string stopValue = value.ToString();
                                            if (stopNode.Attributes["Value"] != null && stopNode.Attributes["Value"].Value != "")
                                                stopValue = stopNode.Attributes["Value"].Value;
                                            stopCondition.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + "" + stopNode.Attributes["Operation"].Value + "'" + stopValue.Replace("'", "''") + "'");
                                        }

                                        if (fieldNode.Attributes["Unique"] != null && fieldNode.Attributes["Unique"].Value == "1")
                                        {
                                            if (unique.Length != 0)
                                                unique.Append(" OR ");
                                            unique.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + "='" + value.ToString().Replace("'", "''") + "'");
                                        }
                                    }
                                    else if (dbtype == OleDbType.Date || dbtype == OleDbType.DBDate || dbtype == OleDbType.DBTime)
                                    {
                                        if (!(value is DateTime))
                                            value = Convert.ToDateTime(value.ToString());

                                        if (stopNode != null)
                                        {
                                            if (stopCondition.Length != 0)
                                                stopCondition.Append(" OR ");

                                            string stopValue = value.ToString();
                                            if (stopNode.Attributes["Value"] != null && stopNode.Attributes["Value"].Value != "")
                                                stopValue = stopNode.Attributes["Value"].Value;
                                            stopCondition.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + stopNode.Attributes["Operation"].Value + "#" + stopValue + "#");
                                        }

                                        if (fieldNode.Attributes["Unique"] != null && fieldNode.Attributes["Unique"].Value == "1")
                                        {
                                            if (unique.Length != 0)
                                                unique.Append(" OR ");
                                            unique.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + "=#" + value + "#");
                                        }
                                    }
                                    else if (dbtype == OleDbType.Integer)
                                    {
                                        if (!(value is Int32))
                                            value = Convert.ToInt32(value.ToString());

                                        if (stopNode != null)
                                        {
                                            if (stopCondition.Length != 0)
                                                stopCondition.Append(" OR ");

                                            string stopValue = value.ToString();
                                            if (stopNode.Attributes["Value"] != null && stopNode.Attributes["Value"].Value != "")
                                                stopValue = stopNode.Attributes["Value"].Value;
                                            stopCondition.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + stopNode.Attributes["Operation"].Value + stopValue);
                                        }

                                        if (fieldNode.Attributes["Unique"] != null && fieldNode.Attributes["Unique"].Value == "1")
                                        {
                                            if (unique.Length != 0)
                                                unique.Append(" OR ");
                                            unique.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + "=" + value);
                                        }
                                    }
                                    else if (dbtype == OleDbType.Decimal)
                                    {
                                        if (!(value is decimal))
                                            value = Convert.ToDecimal(value.ToString());

                                        if (stopNode != null)
                                        {
                                            if (stopCondition.Length != 0)
                                                stopCondition.Append(" OR ");

                                            string stopValue = value.ToString();
                                            if (stopNode.Attributes["Value"] != null && stopNode.Attributes["Value"].Value != "")
                                                stopValue = stopNode.Attributes["Value"].Value;
                                            stopCondition.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + stopNode.Attributes["Operation"].Value + stopValue);
                                        }

                                        if (fieldNode.Attributes["Unique"] != null && fieldNode.Attributes["Unique"].Value == "1")
                                        {
                                            if (unique.Length != 0)
                                                unique.Append(" OR ");
                                            unique.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + "=" + value);
                                        }
                                    }
                                    else if (dbtype == OleDbType.Guid)
                                    {
                                        if (!(value is Guid))
                                            value = new Guid(value.ToString());

                                        if (stopNode != null)
                                        {
                                            if (stopCondition.Length != 0)
                                                stopCondition.Append(" OR ");

                                            string stopValue = value.ToString();
                                            if (stopNode.Attributes["Value"] != null && stopNode.Attributes["Value"].Value != "")
                                                stopValue = stopNode.Attributes["Value"].Value;
                                            stopCondition.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + stopNode.Attributes["Operation"].Value + "{" + stopValue + "}");
                                        }

                                        if (fieldNode.Attributes["Unique"] != null && fieldNode.Attributes["Unique"].Value == "1")
                                        {
                                            if (unique.Length != 0)
                                                unique.Append(" OR ");
                                            unique.Append(property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + "={" + value + "}");
                                        }
                                    }

                                    if (fieldNode.Attributes["MapOnly"] == null || fieldNode.Attributes["MapOnly"].Value != "1")
                                        items[property[SystemModule.Alias.Module.Object.Property.UniqueInnerID] + lang] = value;

                                    break;
                                }
                            }
                        }
                        #endregion

                        #region 检查停止条件
                        if (stopCondition.Length > 0)
                        {
                            DataTable table = _tobll.List(1, 1, stopCondition.ToString(), null);
                            if (table.Rows.Count > 0)
                                break;
                        }
                        #endregion

                        #region 检查唯一性
                        string onExist = "Continue";
                        if (_exportNode.Attributes["OnExist"] != null)
                            onExist = _exportNode.Attributes["OnExist"].Value;

                        DataTable existTable = null;
                        if (unique.Length > 0 && (onExist == "Continue" || onExist == "Stop"))
                        {
                            existTable = _tobll.List(1, 1, unique.ToString(), null);
                            if (existTable.Rows.Count > 0)
                            {
                                if (onExist == "Continue")
                                    continue;
                                else
                                    break;
                            }
                        }
                        #endregion

                        #region 添加额外项
                        foreach (KeyValuePair<string, OleDbType> kvp in _extra)
                        {
                            object value = null;
                            if (kvp.Value == OleDbType.Date || kvp.Value == OleDbType.DBDate || kvp.Value == OleDbType.DBTime)
                            {
                                value = DateTime.Now;
                            }
                            else if (kvp.Value == OleDbType.Integer || kvp.Value == OleDbType.Decimal)
                            {
                                value = Convert.ToInt32(DateTime.Now.ToString("yyyyMMddHHmmssfff"));
                            }
                            else if (kvp.Value == OleDbType.Guid)
                            {
                                value = Guid.NewGuid();
                            }
                            else
                            {
                                value = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                            }

                            items[kvp.Key] = value;
                        }
                        #endregion

                        #region 添加或更新
                        Guid guid = Guid.Empty;
                        if (existTable == null || existTable.Rows.Count == 0)
                        {
                            guid = _tobll.Add(items);
                        }
                        else
                        {
                            guid = (Guid)existTable.Rows[0][guidField];
                            _tobll.Modify((int)existTable.Rows[0][innerIDField], items);
                        }
                        #endregion

                        #region 处理子表导出
                        if (_children == null)
                        {
                            _children = new List<ExportClass>();

                            XmlNodeList childNodes = _exportNode.SelectNodes("Export");
                            foreach (XmlNode childNode in childNodes)
                            {
                                if (childNode.Attributes["Name"] == null || childNode.Attributes["Object"] == null)
                                    continue;

                                ExportClass export = new ExportClass();
                                if (export.Open(_rule, _connectionString, _lang, childNode))
                                    _children.Add(export);
                            }
                        }

                        foreach (ExportClass child in _children)
                        {
                            child.Execute(0, Convert.ToInt32(_reader["ID"]), guid);
                        }
                        #endregion

                        #region OnComplete事件
                        if (parentID == 0 && _exportNode.Attributes["OnComplete"] != null)
                        {
                            _tobll.GetType().InvokeMember(_exportNode.Attributes["OnComplete"].Value, BindingFlags.InvokeMethod, null, _tobll, new object[] { guid });
                        }
                        #endregion
                    }
                    catch (Exception exp)
                    {
                        using (SystemModule.ILog logBll = (SystemModule.ILog)_manager.CreateObject("Log", 0, _lang, false))
                        {
                            Dictionary<string, object> item = new Dictionary<string, object>();
                            item[SystemModule.Alias.Log.Message] = exp.ToString();
                            item[SystemModule.Alias.Log.CreateTime] = DateTime.Now;
                            logBll.Add(item);
                        }
                    }
                }
                _reader.Close();
            }
            public void Close()
            {
                #region 关闭数据库
                if (_reader != null && !_reader.IsClosed)
                    _reader.Close();

                if (_connection != null && _connection.State != ConnectionState.Closed)
                    _connection.Close();
                #endregion

                #region 关闭子导出
                if (_children != null)
                {
                    foreach (ExportClass child in _children)
                    {
                        child.Close();
                    }
                }
                #endregion

                if (_tobll != null)
                    _tobll.Dispose();
            }

            #region Fields
            private Dictionary<string, object> _rule;
            private string _lang;
            private XmlDocument _config;
            private XmlNodeList _fieldNodes;
            private XmlNode _exportNode;
            private Dictionary<string, OleDbType> _extra;
            private DataRow[] _properties;
            private string _connectionString;
            private OleDbConnection _connection = null;
            private OleDbCommand _command = null;
            private OleDbDataReader _reader = null;
            private IDbObject _tobll = null;
            private List<ExportClass> _children;
            #endregion
        }

        public void StartExecute(int id)
        {
            if (_runingRules == null)
                _runingRules = new Dictionary<int, ManualResetEvent>();

            #region 处理Exit事件
            ManualResetEvent exitEvent = null;
            if (_runingRules.ContainsKey(id))
            {
                exitEvent = _runingRules[id];
                if (!exitEvent.WaitOne(0))
                    return;

                exitEvent.Reset();
            }
            else
            {
                exitEvent = new ManualResetEvent(false);
                _runingRules[id] = exitEvent;
            }
            #endregion

            _manager = Manager;

            Dictionary<string, object> state = new Dictionary<string, object>();
            state["RuleInnerID"] = id;
            state["ExitEvent"] = exitEvent;
            ThreadPool.QueueUserWorkItem(new WaitCallback(Run), state);
        }
        public void StartExecute(DataRow task)
        {
            int id = 0;
            if (Regex.IsMatch(task[SystemModule.Alias.Task.Record].ToString(), @"^\d+$"))
                id = Convert.ToInt32(task[SystemModule.Alias.Task.Record]);
            else
                id = GetInnerIDFromGuid(new Guid(task[SystemModule.Alias.Task.Record].ToString()));
            StartExecute(id);
        }
        public void StopExecute(int id)
        {
            if (_runingRules != null && _runingRules.ContainsKey(id))
            {
                _runingRules[id].Set();
            }
        }
        public bool IsRunning(int id)
        {
            if (_runingRules != null && _runingRules.ContainsKey(id))
            {
                if (_runingRules[id].WaitOne(0))
                    return false;
                else
                    return true;
            }
            else
            {
                return false;
            }
        }

        private void Run(object s)
        {
            Dictionary<string, object> state = s as Dictionary<string, object>;
            OleDbConnection connection = null;
            OleDbCommand command = null;
            IRule ruleBll = null;
            ManualResetEvent exitEvent = (ManualResetEvent)state["ExitEvent"];

            try
            {
                #region 获取规则配置
                XmlDocument config = null;
                ruleBll = (IRule)_manager.CreateObject("Rule", InstanceID, Lang, false);
                state["RuleBll"] = ruleBll;

                Dictionary<string, object> rule = ruleBll.Get(state["RuleInnerID"]);
                if (rule[Alias.Rule.Config].ToString() == String.Empty)
                {
                    exitEvent.Set();
                    return;
                }

                config = new XmlDocument();
                config.LoadXml(rule[Alias.Rule.Config].ToString());
                if (config.DocumentElement.Attributes["Name"] == null || config.DocumentElement.Attributes["Name"].Value == "" ||
                    config.DocumentElement.Attributes["Url"] == null || config.DocumentElement.Attributes["Url"].Value == "")
                {
                    exitEvent.Set();
                    return;
                }

                state["Config"] = config;

                #region 修改最后运行事件和运行次数
                Dictionary<string, object> changes = new Dictionary<string, object>();
                changes[Alias.Rule.LastRun] = DateTime.Now;
                changes[Alias.Rule.RunTimes] = Convert.ToInt32(rule[Alias.Rule.RunTimes]) + 1;
                changes[Alias.Rule.EndTime] = DBNull.Value;
                ruleBll.Modify(Convert.ToInt32(rule[Alias.Rule.InnerID]), changes);
                #endregion

                XmlNodeList fieldNodes = config.DocumentElement.SelectNodes("Fields/Field[@Name!='']");
                if (fieldNodes.Count == 0)
                {
                    exitEvent.Set();
                    return;
                }
                #endregion

                #region 获取栏目配置
                Dictionary<string, string> instanceConfig = null;
                using (IInstanceConfig configBll = (IInstanceConfig)_manager.CreateObject("InstanceConfig", InstanceID, Lang, false))
                {
                    instanceConfig = configBll.GetBasicSettings();
                    state["Interval"] = Convert.ToInt32(instanceConfig[Alias.InstanceConfig.Interval]) * 1000;
                }
                #endregion

                #region 检查数据库是否存在。不存在，则创建。
                string db = null;
                string connectionString = instanceConfig[Alias.InstanceConfig.ConnectionString];
                connectionString = connectionString.Replace("{#InstancePath#}", _manager.MapPath(_manager.GetDataPath(InstanceID, null)));
                connectionString = connectionString.Replace("{#WebPath#}", _manager.MapPath(_manager.GetWebPath()));
                connectionString = connectionString.Replace("{#DataPath#}", _manager.MapPath(_manager.GetDataPath(null, null)));
                string[] parts = connectionString.Split(';');
                foreach (string part in parts)
                {
                    string[] pair = part.Split('=');
                    if (pair[0] == "Data Source")
                    {
                        db = pair[1];
                        break;
                    }
                }
                if (db == null)
                {
                    exitEvent.Set();
                    return;
                }

                if (!Directory.Exists(Path.GetDirectoryName(db)))
                    _manager.MakeSureFolderExist(Path.GetDirectoryName(db));
                if (!File.Exists(db))
                {
                    ADOX.Catalog cat = new ADOX.Catalog();
                    cat.Create(connectionString);
                }
                #endregion

                #region 打开数据库
                connection = new OleDbConnection(connectionString);
                command = new OleDbCommand();
                command.Connection = connection;

                state["Connection"] = connection;
                state["Command"] = command;

                connection.Open();
                #endregion

                #region 主表
                //#region 检查数据表是否存在，如果不存在创建一个
                //string tableName = config.DocumentElement.Attributes["Name"].Value;
                //DataTable tables = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, tableName, "TABLE" });
                //if (tables.Rows.Count == 0)
                //{
                //    string sql = "CREATE TABLE [" + tableName + "]([ID] int identity(1,1) UNIQUE PRIMARY KEY,[RuleID] uniqueidentifier,[CreateTime] datetime default now()";
                //    foreach (XmlNode fieldNode in fieldNodes)
                //    {
                //        string dataType = " nvarchar(255)";
                //        if (fieldNode.Attributes["DataType"] != null)
                //        {
                //            if (fieldNode.Attributes["DataType"].Value == "Number")
                //                dataType = " int";
                //            else if (fieldNode.Attributes["DataType"].Value == "Float")
                //                dataType = " decimal(10,3)";
                //            else if (fieldNode.Attributes["DataType"].Value == "Guid")
                //                dataType = " uniqueidentifier";
                //            else if (fieldNode.Attributes["DataType"].Value == "Memo")
                //                dataType = " ntext";
                //            else
                //                dataType = " nvarchar(255)";
                //        }
                //        sql += ",[" + fieldNode.Attributes["Name"].Value + "]" + dataType;
                //    }
                //    sql += ")";

                //    command.CommandText = sql;
                //    command.ExecuteNonQuery();
                //}
                //#endregion

                //#region 检查字段是否存在，不存在，则创建
                //DataTable fieldTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName, null });
                //foreach (XmlNode fieldNode in fieldNodes)
                //{
                //    bool exist = false;
                //    foreach (DataRow fieldRow in fieldTable.Rows)
                //    {
                //        if (fieldNode.Attributes["Name"] == null)
                //            continue;

                //        if (fieldNode.Attributes["Name"].Value == fieldRow["COLUMN_NAME"].ToString())
                //        {
                //            exist = true;
                //            break;
                //        }
                //    }

                //    if (exist)
                //        continue;

                //    string dataType = " nvarchar(255)";
                //    if (fieldNode.Attributes["DataType"] != null)
                //    {
                //        if (fieldNode.Attributes["DataType"].Value == "Number")
                //            dataType = " int";
                //        else if (fieldNode.Attributes["DataType"].Value == "Float")
                //            dataType = " decimal(10,3)";
                //        else if (fieldNode.Attributes["DataType"].Value == "Guid")
                //            dataType = " uniqueidentifier";
                //        else if (fieldNode.Attributes["DataType"].Value == "Memo")
                //            dataType = " ntext";
                //        else
                //            dataType = " nvarchar(255)";
                //    }

                //    command.CommandText = "ALTER TABLE [" + tableName + "] ADD [" + fieldNode.Attributes["Name"].Value + "]" + dataType;
                //    command.ExecuteNonQuery();
                //}
                //#endregion
                #endregion

                #region 准备数据表
                string tableName = config.DocumentElement.Attributes["Name"].Value;
                XmlNodeList subRules = config.SelectNodes("//Rule[@Name!='']");
                foreach (XmlNode subRule in subRules)
                {
                    XmlNodeList subFieldNodes = subRule.SelectNodes("Fields/Field[@Name!='']");
                    if (subFieldNodes.Count == 0)
                        continue;

                    #region 检查数据表是否存在，如果不存在创建一个
                    string subTableName = subRule.Attributes["Name"].Value;
                    DataTable tables = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, subTableName, "TABLE" });
                    if (tables.Rows.Count == 0)
                    {
                        string sql = "CREATE TABLE [" + subTableName + "]([ID] int identity(1,1) UNIQUE PRIMARY KEY,[RuleID] uniqueidentifier,[CreateTime] datetime default now()";
                        if (tableName != subTableName)
                            sql += ",[ParentID] int";

                        foreach (XmlNode fieldNode in subFieldNodes)
                        {
                            string dataType = " nvarchar(255)";
                            if (fieldNode.Attributes["DataType"] != null)
                            {
                                if (fieldNode.Attributes["DataType"].Value == "Number")
                                    dataType = " int";
                                else if (fieldNode.Attributes["DataType"].Value == "Float")
                                    dataType = " decimal(10,3)";
                                else if (fieldNode.Attributes["DataType"].Value == "Guid")
                                    dataType = " uniqueidentifier";
                                else if (fieldNode.Attributes["DataType"].Value == "Memo")
                                    dataType = " ntext";
                                else
                                    dataType = " nvarchar(255)";
                            }
                            sql += ",[" + fieldNode.Attributes["Name"].Value + "]" + dataType;
                        }
                        sql += ")";

                        command.CommandText = sql;
                        command.ExecuteNonQuery();

                        #region 创建外键
                        if (tableName != subTableName)
                        {
                            command.CommandText = "ALTER TABLE [" + subTableName + "] ADD CONSTRAINT [fk_" + subTableName + "] FOREIGN KEY ([ParentID]) REFERENCES [" + tableName + "]([ID]) ON DELETE CASCADE ON UPDATE CASCADE";
                            command.ExecuteNonQuery();
                        }
                        #endregion
                    }
                    #endregion

                    #region 检查字段是否存在，不存在，则创建
                    DataTable fieldTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, subTableName, null });
                    foreach (XmlNode fieldNode in subFieldNodes)
                    {
                        bool exist = false;
                        foreach (DataRow fieldRow in fieldTable.Rows)
                        {
                            if (fieldNode.Attributes["Name"].Value == fieldRow["COLUMN_NAME"].ToString())
                            {
                                exist = true;
                                break;
                            }
                        }

                        if (exist)
                            continue;

                        string dataType = " nvarchar(255)";
                        if (fieldNode.Attributes["DataType"] != null)
                        {
                            if (fieldNode.Attributes["DataType"].Value == "Number")
                                dataType = " int";
                            else if (fieldNode.Attributes["DataType"].Value == "Float")
                                dataType = " decimal(10,3)";
                            else if (fieldNode.Attributes["DataType"].Value == "Guid")
                                dataType = " uniqueidentifier";
                            else if (fieldNode.Attributes["DataType"].Value == "Memo")
                                dataType = " ntext";
                            else
                                dataType = " nvarchar(255)";
                        }

                        command.CommandText = "ALTER TABLE [" + subTableName + "] ADD [" + fieldNode.Attributes["Name"].Value + "]" + dataType;
                        command.ExecuteNonQuery();
                    }
                    #endregion
                }
                #endregion

                #region 开始采集
                #region OnExist
                if (config.DocumentElement.Attributes["OnExist"] != null && Regex.IsMatch(config.DocumentElement.Attributes["OnExist"].Value, "^(Continue|Stop|Add|Update)$"))
                    state["OnExist"] = config.DocumentElement.Attributes["OnExist"].Value;
                else
                    state["OnExist"] = "Continue";
                #endregion

                #region Index, StartIndex, EndIndex
                int startIndex = 0;
                int endIndex = 0;
                if (config.DocumentElement.Attributes["StartIndex"] != null && Regex.IsMatch(config.DocumentElement.Attributes["StartIndex"].Value, @"\d+") && config.DocumentElement.Attributes["EndIndex"] != null && Regex.IsMatch(config.DocumentElement.Attributes["EndIndex"].Value, @"\d+"))
                {
                    startIndex = Convert.ToInt32(config.DocumentElement.Attributes["StartIndex"].Value);
                    endIndex = Convert.ToInt32(config.DocumentElement.Attributes["EndIndex"].Value);
                }

                string url = null;
                if (!Convert.IsDBNull(rule[Alias.Rule.LastID]))
                {
                    string pattern = config.DocumentElement.Attributes["Url"].Value;
                    if (pattern.IndexOf("{Index}") != -1)
                    {
                        pattern = pattern.Replace(".", @"\.").Replace("?", @"\?").Replace("{Index}", @"(?<v>\d+)");
                        Match match = Regex.Match(rule[Alias.Rule.LastID].ToString(), pattern, RegexOptions.IgnoreCase);
                        if (match.Success && match.Groups["v"].Success)
                            state["Index"] = Convert.ToInt32(match.Groups["v"].Value);
                    }

                    url = rule[Alias.Rule.LastID].ToString();
                }
                else
                {
                    url = config.DocumentElement.Attributes["Url"].Value;
                    if (url.IndexOf("{Index}") != -1)
                    {
                        url = url.Replace("{Index}", startIndex.ToString());
                        state["Index"] = startIndex;
                    }
                }
                #endregion

                #region Duration和DateField
                if (config.DocumentElement.Attributes["Duration"] != null && Regex.IsMatch(config.DocumentElement.Attributes["Duration"].Value, @"\d+") && config.DocumentElement.Attributes["DateField"] != null && config.DocumentElement.SelectSingleNode("Fields/Field[@Name='" + config.DocumentElement.Attributes["DateField"].Value + "']") != null)
                {
                    state["Duration"] = Convert.ToInt32(config.DocumentElement.Attributes["Duration"].Value);
                    state["DateField"] = config.DocumentElement.Attributes["DateField"].Value;
                }
                #endregion

				#region Cookie
				if (config.DocumentElement.Attributes["Cookie"] != null && config.DocumentElement.Attributes["Cookie"].Value != "")
				{
					string[] cookies = config.DocumentElement.Attributes["Cookie"].Value.Split(';');
					CookieContainer container = new CookieContainer();
					for (int i = 0; i < cookies.Length; i++)
					{
						string[] pair = cookies[i].Split('=');
						if (pair.Length == 0)
							continue;

						Uri target = new Uri(config.DocumentElement.Attributes["Url"].Value);
						Cookie cookie = new Cookie(pair[0], pair[1], "/", target.Host);
						container.Add(cookie);
					}

					if (container.Count > 0)
						state["Cookie"] = container;
				}
				#endregion

				#region Export
				state["AutoExport"] = rule[Alias.Rule.AutoExport];
                if (Convert.ToBoolean(state["AutoExport"]))
                {
                    ExportClass export = new ExportClass();
                    if (export.Open(rule, connectionString, Lang, null))
                        state["Export"] = export;
                }
                #endregion

                state["RuleID"] = rule[Alias.Rule.ID];
                state["UserAgent"] = rule[Alias.Rule.UserAgent];
                state["TableName"] = tableName;

                while (true)
                {
                    state["Rule"] = config.DocumentElement;
                    ExecutePage(state, url, 0);

                    if (((ManualResetEvent)state["ExitEvent"]).WaitOne(0))
                        break;

                    #region 下一页
                    XmlNode nextPageNode = config.DocumentElement.SelectSingleNode("NextPage");
                    bool hazNext = nextPageNode != null && state.ContainsKey("Content") && nextPageNode.Attributes["Regex"] != null;
                    if (hazNext)
                    {
                        Match match = Regex.Match(state["Content"].ToString(), nextPageNode.Attributes["Regex"].Value, RegexOptions.IgnoreCase);
                        hazNext = match.Success;
                        if (hazNext)
                        {
                            string input = String.Empty;
                            if (nextPageNode.Attributes["Group"] != null && match.Groups[nextPageNode.Attributes["Group"].Value].Success)
                                input = match.Groups[nextPageNode.Attributes["Group"].Value].Value;
                            else
                                input = match.Value;

                            if (nextPageNode.Attributes["Url"] != null)
                            {
                                string expression = nextPageNode.Attributes["Url"].Value;

                                state["Input"] = input;
                                state["Url"] = config.DocumentElement.Attributes["Url"].Value;
                                url = ExecuteFunction(expression, state);
                            }
                            else
                            {
                                url = input;
                            }
                        }
                    }
                    #endregion

                    #region 下一索引
                    if (!hazNext)
                    {
                        url = config.DocumentElement.Attributes["Url"].Value;
                        if (url.IndexOf("{Index}") == -1 || startIndex == endIndex || !state.ContainsKey("Index"))
                            break;

                        int index = 0;
                        if (startIndex < endIndex)
                        {
                            index = (int)state["Index"] + 1;
                            if (index > endIndex)
                                break;
                        }
                        else
                        {
                            index = (int)state["Index"] - 1;
                            if (index < startIndex)
                                break;
                        }

                        state["Index"] = index;
                        url = url.Replace("{Index}", index.ToString());
                    }
                    #endregion
                }
                #endregion

                #region 采集完毕，没有Content表示因错误自然退出
                if (state.ContainsKey("Content"))
                {
                    changes.Clear();
                    changes[Alias.Rule.EndTime] = DateTime.Now;
                    if (state.ContainsKey("Duration"))
                        changes[Alias.Rule.LastID] = DBNull.Value;
                    ruleBll.Modify(Convert.ToInt32(rule[Alias.Rule.InnerID]), changes);
                }
                #endregion
            }
            catch (Exception exp)
            {
                #region 记录系统日志
                using (SystemModule.ILog bll = (SystemModule.ILog)_manager.CreateObject("Log", 0, Lang, false))
                {
                    Dictionary<string, object> item = new Dictionary<string, object>();
                    item[SystemModule.Alias.Log.Message] = exp.ToString();
                    item[SystemModule.Alias.Log.CreateTime] = DateTime.Now;
                    bll.Add(item);
                }
                #endregion

                #region 异常终止线程时，定时5分钟继续执行
                using (SystemModule.ITask taskBll = (SystemModule.ITask)_manager.CreateObject("Task", 0, Lang, false))
                {
                    DataRow instance = _manager.Instances.Select(SystemModule.Alias.Instance.InnerID + "=" + InstanceID)[0];

                    Dictionary<string, object> task = new Dictionary<string, object>();
                    task[SystemModule.Alias.Task.Name] = "采集异常终止时，定时5分钟继续执行";
                    task[SystemModule.Alias.Task.InstanceID] = instance[SystemModule.Alias.Instance.ID];
                    task[SystemModule.Alias.Task.Object] = "Rule";
                    task[SystemModule.Alias.Task.Lang] = Lang;
                    task[SystemModule.Alias.Task.Operation] = "StartExecute";
                    task[SystemModule.Alias.Task.Record] = state["RuleInnerID"].ToString();
                    task[SystemModule.Alias.Task.Every] = "Once";
                    task[SystemModule.Alias.Task.StartTime] = DateTime.Now.AddMinutes(5);

                    taskBll.Add(task);
                }

                _manager.UpdateTask();
                #endregion
            }
            finally
            {
                #region 关闭数据库
                if (connection != null && connection.State != ConnectionState.Closed)
                    connection.Close();
                #endregion

                if (ruleBll != null)
                    ruleBll.Dispose();

                #region 关闭Export
                if (state.ContainsKey("Export"))
                {
                    ExportClass export = (ExportClass)state["Export"];
                    export.Close();
                }
                #endregion

                exitEvent.Set();
            }
        }
        private void ExecutePage(Dictionary<string, object> state, string nextPage, int id)
        {
            XmlNode rule = (XmlNode)state["Rule"];
            XmlNodeList fieldNodes = rule.SelectNodes("Fields/Field[@Name!='']");
            if (fieldNodes.Count == 0)
                return;

            OleDbConnection connection = (OleDbConnection)state["Connection"];
            OleDbCommand command = (OleDbCommand)state["Command"];

            #region 读取内容
            string requestUrl = null;
            string content = null;

            try
            {
                if (nextPage != null)
                {
                    requestUrl = nextPage;
                }
                else if (rule.Attributes["UrlField"] != null)
                {
                    command.CommandText = "SELECT TOP 1 [" + rule.Attributes["UrlField"].Value + "] FROM [" + state["TableName"] + "] WHERE [ID]=" + id;
                    requestUrl = command.ExecuteScalar().ToString();
                }
                else if (rule.Attributes["Url"] != null)
                {
                    requestUrl = ExecuteFunction(rule.Attributes["Url"].Value, state);
                }
                else//表示从当前内容中再次查找
                {
                    if (!state.ContainsKey("Url") || !state.ContainsKey("Content"))
                        return;

                    requestUrl = state["Url"].ToString();
                    content = state["Content"].ToString();
                    goto SamePage;
                }

                if (!requestUrl.StartsWith("http://"))
                    return;

				#region 处理字符编码
				Encoding encoding = null;
                if (rule.Attributes["Charset"] != null && (rule.Attributes["Charset"].Value == "936" || rule.Attributes["Charset"].Value.Equals("GB2312", StringComparison.InvariantCultureIgnoreCase)))
                    encoding = Encoding.GetEncoding(936);
                else if (rule.Attributes["Charset"] != null && (rule.Attributes["Charset"].Value == "950" || rule.Attributes["Charset"].Value.Equals("BIG5", StringComparison.InvariantCultureIgnoreCase)))
                    encoding = Encoding.GetEncoding(950);
                else
                    encoding = Encoding.UTF8;
				#endregion

				HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
				if (state["UserAgent"].ToString() != "")
					request.UserAgent = state["UserAgent"].ToString();
				else
					request.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:12.0;) Gecko/20100101 Firefox/12.0";
				request.Referer = requestUrl;
                request.Timeout = 30000;
				if (state.ContainsKey("Cookie"))
					request.CookieContainer = (CookieContainer)state["Cookie"];
				HttpWebResponse response = (HttpWebResponse)request.GetResponse();
				if (state.ContainsKey("Cookie"))
					response.Cookies = ((CookieContainer)state["Cookie"]).GetCookies(request.RequestUri);
                StreamReader reader = new StreamReader(response.GetResponseStream(), encoding);
                content = reader.ReadToEnd();
                reader.Close();
                reader = null;
                request = null;
                response = null;
            }
            catch (WebException exp)
            {
                if (exp.Response == null || exp.Status != WebExceptionStatus.ProtocolError)
                {
                    using (SystemModule.ILog bll = (SystemModule.ILog)_manager.CreateObject("Log", 0, Lang, false))
                    {
                        Dictionary<string, object> item = new Dictionary<string, object>();
                        item[SystemModule.Alias.Log.Message] = exp.ToString();
                        item[SystemModule.Alias.Log.CreateTime] = DateTime.Now;
                        bll.Add(item);
                    }

                    XmlNode onError = ((XmlNode)state["Rule"]).OwnerDocument.DocumentElement.Attributes["OnError"];
                    if (onError != null && onError.Value == "Stop")
                        ((ManualResetEvent)state["ExitEvent"]).Set();

                    state.Remove("Content");

                    return;
                }
                else
                {
                    HttpWebResponse response = (HttpWebResponse)exp.Response;
                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet));
                    content = reader.ReadToEnd();
                }
            }
            #endregion

            #region 记录最后操作的地址
            if (id == 0 && !state.ContainsKey("ParentID"))
            {
                IRule ruleBll = (IRule)state["RuleBll"];
                Dictionary<string, object> changes = new Dictionary<string, object>();
                changes[Alias.Rule.LastID] = requestUrl;
                ruleBll.Modify(Convert.ToInt32(state["RuleInnerID"]), changes);
            }
            #endregion

            #region 缩小范围
            if (rule.Attributes["Section"] != null)
            {
                Match match = Regex.Match(content, rule.Attributes["Section"].Value, RegexOptions.IgnoreCase);
                if (match.Success)
                    content = match.Value;
            }
            #endregion

        SamePage:
            #region 内容页
            if (rule.Attributes["Regex"] == null)
            {
                state["Url"] = requestUrl;
                state["Rule"] = rule;
                state["FieldNodes"] = fieldNodes;
                state["Content"] = content;
                WriteOneRecord(state, id);
            }
            #endregion
            #region 列表页
            else
            {
                MatchCollection matches = Regex.Matches(content, rule.Attributes["Regex"].Value, RegexOptions.IgnoreCase);
                foreach (Match match in matches)
                {
                    state["Url"] = requestUrl;
                    state["Rule"] = rule;
                    state["FieldNodes"] = fieldNodes;
                    state["Content"] = match.Value;
                    WriteOneRecord(state, id);
                }
            }
            #endregion

            state["Content"] = content;
        }
        private void WriteOneRecord(Dictionary<string, object> state, int id)
        {
            if (((ManualResetEvent)state["ExitEvent"]).WaitOne((int)state["Interval"]))
                return;

            OleDbConnection connection = (OleDbConnection)state["Connection"];
            OleDbCommand command = (OleDbCommand)state["Command"];
            XmlNodeList fieldNodes = (XmlNodeList)state["FieldNodes"];

            #region 数据库中读取在函数里可能会用到的字段值。
            if (id > 0)
            {
                List<string> select = null;
                XmlNodeList allfields = ((XmlNode)state["Rule"]).OwnerDocument.DocumentElement.SelectNodes("Fields/Field[@Name!='']");
                foreach (XmlNode fieldNode in fieldNodes)
                {
                    if (fieldNode.Attributes["Value"] == null)
                        continue;

                    string value = fieldNode.Attributes["Value"].Value;
                    foreach (XmlNode field in allfields)
                    {
                        if (value.IndexOf(field.Attributes["Name"].Value) != -1)
                        {
                            #region 如果这一次重新设置值，并且不是他自己的话，无需从数据库中读取
                            bool dont = false;
                            foreach (XmlNode n in fieldNodes)
                            {
                                if (n.Attributes["Name"].Value == field.Attributes["Name"].Value && n.Attributes["Name"].Value != fieldNode.Attributes["Name"].Value && n.Attributes["Regex"] != null)
                                {
                                    dont = true;
                                    break;
                                }
                            }
                            if (dont)
                                continue;
                            #endregion

                            if (select == null)
                                select = new List<string>();
                            select.Add(field.Attributes["Name"].Value);
                        }
                    }
                }

                if (select != null)
                {
                    string sql = null;
                    foreach (string name in select)
                    {
                        if (sql == null)
                            sql = "SELECT TOP 1 [" + name + "]";
                        else
                            sql += ",[" + name + "]";
                    }
                    sql += " FROM [" + state["TableName"] + "] WHERE [ID]=" + id;

                    command.CommandText = sql;
                    OleDbDataReader reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        foreach (string name in select)
                        {
                            XmlNode node = null;
                            foreach (XmlNode fieldNode in fieldNodes)
                            {
                                if (fieldNode.Attributes["Name"].Value == name)
                                {
                                    node = fieldNode;
                                    break;
                                }
                            }

                            #region 暂时不考虑添加的情况。即总的字段列表中存在，但是当前的fieldNodes中不存在。
                            if (node != null)
                            {
                                if (node.Attributes["ParsedValue"] == null)
                                    node.Attributes.Append(node.OwnerDocument.CreateAttribute("ParsedValue"));
                                node.Attributes["ParsedValue"].Value = reader[name].ToString();
                            }
                            #endregion
                        }
                    }
                    reader.Close();
                }
            }
            #endregion

            #region 分析并获取字段值
            foreach (XmlNode fieldNode in fieldNodes)
			{
				if (fieldNode.Attributes["Regex"] != null)
                {
                    string input = String.Empty;
                    Match fieldMatch = Regex.Match(state["Content"].ToString(), fieldNode.Attributes["Regex"].Value, RegexOptions.IgnoreCase);
                    if (fieldMatch.Success)
                    {
                        if (fieldNode.Attributes["Group"] != null && fieldMatch.Groups[fieldNode.Attributes["Group"].Value].Success)
                            input = fieldMatch.Groups[fieldNode.Attributes["Group"].Value].Value;
                        else
                            input = fieldMatch.Value;
                    }

                    if (fieldNode.Attributes["ParsedValue"] == null)
                        fieldNode.Attributes.Append(fieldNode.OwnerDocument.CreateAttribute("ParsedValue"));

                    if (fieldNode.Attributes["Value"] != null && fieldNode.Attributes["Value"].Value != "")
                    {
                        state["Input"] = input;
                        fieldNode.Attributes["ParsedValue"].Value = ExecuteFunction(fieldNode.Attributes["Value"].Value, state);
                    }
                    else
                    {
                        fieldNode.Attributes["ParsedValue"].Value = input;
                    }
                }
                else if (fieldNode.Attributes["Value"] != null && fieldNode.Attributes["Value"].Value != "")
                {
                    if (fieldNode.Attributes["ParsedValue"] == null)
                        fieldNode.Attributes.Append(fieldNode.OwnerDocument.CreateAttribute("ParsedValue"));

                    state["Input"] = String.Empty;
                    fieldNode.Attributes["ParsedValue"].Value = ExecuteFunction(fieldNode.Attributes["Value"].Value, state);
                }

                #region 检查Duration
				if (state.ContainsKey("Duration") && state.ContainsKey("DateField") && state["DateField"].ToString() == fieldNode.Attributes["Name"].Value && fieldNode.Attributes["ParsedValue"] != null)
                {
                    DateTime date;
                    bool isDate = DateTime.TryParse(fieldNode.Attributes["ParsedValue"].Value, out date);
                    if (isDate && DateTime.Now.Subtract(date).TotalMinutes > (int)state["Duration"])
                    {
                        ((ManualResetEvent)state["ExitEvent"]).Set();

						if (id > 0)
						{
							command.CommandText = "DELETE FROM [" + state["TableName"] + "] WHERE [ID]=" + id;
							command.ExecuteNonQuery();
						}
                        return;
                    }
                }
                #endregion

                #region 下载
                if (fieldNode.Attributes["Download"] != null && fieldNode.Attributes["Download"].Value == "1" && fieldNode.Attributes["ParsedValue"].Value.StartsWith("http://"))
                {
                    string path = _manager.GetDataPath(InstanceID, null) + "file/" + state["RuleID"] + "/";
                    string absPath = _manager.MapPath(path).Replace('/', '\\');

                    try
                    {
                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fieldNode.Attributes["ParsedValue"].Value);
                        request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)";
                        request.Timeout = 30000;
                        WebResponse response = request.GetResponse();
                        Stream stream = response.GetResponseStream();

                        string ext = Path.GetExtension(fieldNode.Attributes["ParsedValue"].Value);
                        if (String.IsNullOrEmpty(ext))
                        {
                            switch (response.ContentType)
                            {
                                case "image/gif":
                                    ext = ".gif";
                                    break;
                                case "image/jpeg":
                                case "image/pjpeg":
                                    ext = ".jpg";
                                    break;
                                case "image/png":
                                case "image/x-png":
                                case "application/x-png":
                                    ext = ".png";
                                    break;
                                case "audio/mpeg3":
                                case "audio/mp3":
                                    ext = ".mp3";
                                    break;
                                case "audio/x-ms-wma":
                                    ext = ".wma";
                                    break;
                                case "application/x-shockwave-flash":
                                    ext = ".swf";
                                    break;
                                case "application/x-bmp":
                                    ext = ".bmp";
                                    break;
                            }
                        }

                        string fileName = String.Empty;
                        _manager.MakeSureFolderExist(absPath);
                        if (id > 0)
                        {
                            #region 删除先前的文件
                            string[] files = Directory.GetFiles(absPath, id + "_*", SearchOption.TopDirectoryOnly);
                            foreach (string f in files)
                            {
                                File.Delete(f);
                            }
                            #endregion

                            fileName = id + "_";
                        }
                        fileName += DateTime.Now.ToString("yyyyMMddHHmmssfff") + ext;
                        path += fileName;
                        absPath += fileName;

                        int size = 10 * 1024;
                        byte[] buffer = new byte[size];
                        FileStream file = File.OpenWrite(absPath);
                        while (true)
                        {
                            int read = stream.Read(buffer, 0, size);
                            if (read == 0)
                                break;

                            file.Write(buffer, 0, read);
                        }
                        file.Close();
                        request = null;
                        response = null;

                        fieldNode.Attributes["ParsedValue"].Value = path;
                    }
                    catch (Exception exp)
                    {
                        using (SystemModule.ILog bll = (SystemModule.ILog)_manager.CreateObject("Log", 0, Lang, false))
                        {
                            Dictionary<string, object> item = new Dictionary<string, object>();
                            item[SystemModule.Alias.Log.Message] = "下载失败：" + path + "<br />" + exp.ToString();
                            item[SystemModule.Alias.Log.CreateTime] = DateTime.Now;
                            bll.Add(item);
                        }
                    }
                }
                #endregion

				#region 文字识别
				if (fieldNode.Attributes["Ocr"] != null && fieldNode.Attributes["Ocr"].Value != "" && fieldNode.Attributes["ParsedValue"].Value.StartsWith("/"))
				{
					string absPath = _manager.MapPath(fieldNode.Attributes["ParsedValue"].Value).Replace('/', '\\');
					string text = String.Empty;

					try
					{
						MODI.Document doc = new MODI.Document();
						doc.Create(absPath);
						MODI.Image image;
						MODI.Layout layout;
						doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true);
						for (int i = 0; i < doc.Images.Count; i++)
						{
							image = doc.Images[i];
							layout = image.Layout;
							text += layout.Text;
						}
					}
					catch (Exception exp)
					{
						using (SystemModule.ILog bll = (SystemModule.ILog)_manager.CreateObject("Log", 0, Lang, false))
						{
							Dictionary<string, object> item = new Dictionary<string, object>();
							item[SystemModule.Alias.Log.Message] = exp.ToString();
							item[SystemModule.Alias.Log.CreateTime] = DateTime.Now;
							bll.Add(item);
						}
					}

					if (fieldNode.Attributes["Ocr"].Value == "1")
					{
						fieldNode.Attributes["ParsedValue"].Value = text;
					}
					else
					{
						state["Input"] = text;
						fieldNode.Attributes["ParsedValue"].Value = ExecuteFunction(fieldNode.Attributes["Ocr"].Value, state);
					}
				}
				#endregion
			}
            #endregion

            #region 检查On条件
            XmlNodeList ons = ((XmlNode)state["Rule"]).SelectNodes("Ons/On[@Field!='']");
            foreach (XmlNode on in ons)
            {
                foreach (XmlNode fieldNode in fieldNodes)
                {
                    if (fieldNode.Attributes["ParsedValue"] == null)
                        continue;

                    if (fieldNode.Attributes["Name"].Value != on.Attributes["Field"].Value)
                        continue;

                    string value = on.Attributes["Value"].Value;
                    if (value.StartsWith("/") && value.EndsWith("/"))
                    {
                        if (!Regex.IsMatch(fieldNode.Attributes["ParsedValue"].Value, value.Substring(1, value.Length - 2), RegexOptions.IgnoreCase))
                            continue;
                    }
                    else
                    {
                        if (fieldNode.Attributes["ParsedValue"].Value != value)
                            continue;
                    }

                    if (on.Attributes["Action"] != null && on.Attributes["Action"].Value == "Stop")
                        ((ManualResetEvent)state["ExitEvent"]).Set();

                    return;
                }
            }
            #endregion

            #region 检查唯一项是否冲突
            if (state["OnExist"].ToString() != "Add")
            {
                string where = null;
                command.Parameters.Clear();
                foreach (XmlNode fieldNode in fieldNodes)
                {
                    if (fieldNode.Attributes["ParsedValue"] == null)
                        continue;

                    if (fieldNode.Attributes["Unique"] == null || fieldNode.Attributes["Unique"].Value != "1")
                        continue;

                    if (where != null)
                        where += " OR ";

                    where += "[" + fieldNode.Attributes["Name"].Value + "]=@" + fieldNode.Attributes["Name"].Value;

                    OleDbType dataType = OleDbType.VarWChar;
                    if (fieldNode.Attributes["DataType"] != null)
                    {
                        if (fieldNode.Attributes["DataType"].Value == "Number")
                            dataType = OleDbType.Integer;
                        else if (fieldNode.Attributes["DataType"].Value == "Float")
                            dataType = OleDbType.Decimal;
                        else if (fieldNode.Attributes["DataType"].Value == "Guid")
                            dataType = OleDbType.Guid;
                        else if (fieldNode.Attributes["DataType"].Value == "Memo")
                            dataType = OleDbType.LongVarWChar;
                        else
                            dataType = OleDbType.VarWChar;
                    }

                    command.Parameters.Add("@" + fieldNode.Attributes["Name"].Value, dataType).Value = fieldNode.Attributes["ParsedValue"].Value;
                }

                if (where != null)
                {
                    command.CommandText = "SELECT TOP 1 [ID] FROM [" + state["TableName"] + "] WHERE (" + where + ") AND [RuleID]=@RuleID";
                    command.Parameters.Add("@RuleID", OleDbType.Guid).Value = state["RuleID"];

                    object temp = command.ExecuteScalar();
                    if (temp != null)
                    {
                        if (state["OnExist"].ToString() == "Update")
                        {
                            id = Convert.ToInt32(temp);
                        }
                        else if (state["OnExist"].ToString() == "Continue")
                        {
                            return;
                        }
                        else if (state["OnExist"].ToString() == "Stop")
                        {
                            ((ManualResetEvent)state["ExitEvent"]).Set();

							if (id > 0)
							{
								command.CommandText = "DELETE FROM [" + state["TableName"] + "] WHERE [ID]=" + id;
								command.ExecuteNonQuery();
							}
							return;
                        }
                    }
                }
            }
            #endregion

            command.Parameters.Clear();
            #region 如果没有记录，插入新记录
            if (id == 0)
            {
                string names = null;
                string values = null;

                foreach (XmlNode fieldNode in fieldNodes)
                {
                    if (fieldNode.Attributes["ParsedValue"] == null)
                        continue;

                    if (names == null)
                    {
                        names = "[RuleID]";
                        values = "@RuleID";
                        command.Parameters.Add("@RuleID", OleDbType.Guid).Value = state["RuleID"];

                        #region 如果是附表，则设置主表ID
                        if (state.ContainsKey("ParentID"))
                        {
                            names += ",[ParentID]";
                            values += ",@ParentID";
                            command.Parameters.Add("@ParentID", OleDbType.Integer).Value = state["ParentID"];
                        }
                        #endregion
                    }

                    names += ",[" + fieldNode.Attributes["Name"].Value + "]";
                    values += ",@" + fieldNode.Attributes["Name"].Value;

                    OleDbType dataType = OleDbType.VarWChar;
                    if (fieldNode.Attributes["DataType"] != null)
                    {
                        if (fieldNode.Attributes["DataType"].Value == "Number")
                            dataType = OleDbType.Integer;
                        else if (fieldNode.Attributes["DataType"].Value == "Float")
                            dataType = OleDbType.Decimal;
                        else if (fieldNode.Attributes["DataType"].Value == "Guid")
                            dataType = OleDbType.Guid;
                        else if (fieldNode.Attributes["DataType"].Value == "Memo")
                            dataType = OleDbType.LongVarWChar;
                        else
                            dataType = OleDbType.VarWChar;
                    }

                    command.Parameters.Add("@" + fieldNode.Attributes["Name"].Value, dataType).Value = fieldNode.Attributes["ParsedValue"].Value;
                }

				command.CommandText = "INSERT INTO [" + state["TableName"] + "](" + names + ") VALUES(" + values + ")";
				command.ExecuteNonQuery();
			}
            #endregion
            #region 如果已有记录，更新现有记录
            else
            {
                string sets = null;

                foreach (XmlNode fieldNode in fieldNodes)
                {
                    if (fieldNode.Attributes["ParsedValue"] == null/* || String.IsNullOrEmpty(fieldNode.Attributes["ParsedValue"].Value)*/)
                        continue;

                    if (sets != null)
                        sets += ",";
                    sets += "[" + fieldNode.Attributes["Name"].Value + "]=@" + fieldNode.Attributes["Name"].Value;

                    OleDbType dataType = OleDbType.VarWChar;
                    if (fieldNode.Attributes["DataType"] != null)
                    {
                        if (fieldNode.Attributes["DataType"].Value == "Number")
                            dataType = OleDbType.Integer;
                        else if (fieldNode.Attributes["DataType"].Value == "Float")
                            dataType = OleDbType.Decimal;
                        else if (fieldNode.Attributes["DataType"].Value == "Guid")
                            dataType = OleDbType.Guid;
                        else if (fieldNode.Attributes["DataType"].Value == "Memo")
                            dataType = OleDbType.LongVarWChar;
                        else
                            dataType = OleDbType.VarWChar;
                    }

                    command.Parameters.Add("@" + fieldNode.Attributes["Name"].Value, dataType).Value = fieldNode.Attributes["ParsedValue"].Value;
                }

                if (command.Parameters.Count > 0)
                {
                    command.CommandText = "UPDATE [" + state["TableName"] + "] SET " + sets + " WHERE [ID]=" + id;
                    command.ExecuteNonQuery();
                }
            }
            #endregion

            #region 处理子查询
            XmlNode rule = (XmlNode)state["Rule"];
            XmlNodeList subRules = rule.SelectNodes("Rule");
            int parentID = id;
            if (id == 0 && (subRules.Count > 0 || !state.ContainsKey("ParentID") && Convert.ToBoolean(state["AutoExport"])))
            {
                command.CommandText = "SELECT TOP 1 [ID] FROM " + state["TableName"] + " ORDER BY [ID] DESC";
                parentID = Convert.ToInt32(command.ExecuteScalar().ToString());
            }

            foreach (XmlNode subRule in subRules)
            {
                #region 设置附表
                string oldTable = null;
                if (subRule.Attributes["Name"] != null && subRule.Attributes["Name"].Value != state["TableName"].ToString())
                {
                    oldTable = state["TableName"].ToString();
                    state["TableName"] = subRule.Attributes["Name"].Value;
                    state["ParentID"] = parentID;
                    parentID = 0;
                }
                #endregion

                string url = null;
                while (true)
                {
                    state["Rule"] = subRule;
                    ExecutePage(state, url, parentID);

                    #region 下一页
                    XmlNode nextPageNode = subRule.SelectSingleNode("NextPage");
                    if (nextPageNode == null || !state.ContainsKey("Content"))
                        break;

                    Match match = Regex.Match(state["Content"].ToString(), nextPageNode.Attributes["Regex"].Value, RegexOptions.IgnoreCase);
                    if (!match.Success)
                        break;

                    string input = String.Empty;
                    if (nextPageNode.Attributes["Group"] != null && match.Groups[nextPageNode.Attributes["Group"].Value].Success)
                        input = match.Groups[nextPageNode.Attributes["Group"].Value].Value;
                    else
                        input = match.Value;

                    string expression = String.Empty;
                    if (nextPageNode.Attributes["Url"] != null)
                        expression = nextPageNode.Attributes["Url"].Value;

                    state["Input"] = input;
                    url = ExecuteFunction(expression, state);
                    #endregion
                }

                #region 恢复主表
                if (oldTable != null)
                {
                    state["TableName"] = oldTable;
                    parentID = (int)state["ParentID"];
                    state.Remove("ParentID");
                }
                #endregion
            }
            #endregion

            #region 导出（设置导出，并且没有出错时）
            if (id == 0 && parentID > 0 && state.ContainsKey("Export") && state.ContainsKey("Content"))
            {
                #region 因为刚刚更新的内容马上获取不到，因此停留一秒钟再获取
                Thread.Sleep(1000);
                #endregion

                ExportClass export = (ExportClass)state["Export"];
                export.Execute(parentID, 0, Guid.Empty);
            }
            #endregion
        }

        private string ExecuteFunction(string expression, Dictionary<string, object> state)
        {
            Function function = ParseFunction(expression);
            if (function == null)
                return Function.GetVarValue(state, expression);

            return function.Execute(state);
        }
        private Function ParseFunction(string expression)
        {
            #region 获取函数名
            Match match = Regex.Match(expression, @"^(?<n>[a-z0-9_]+)\((?<p>.*?)\)$", RegexOptions.IgnoreCase);
            if (!match.Success)
                return null;

            string name = match.Groups["n"].Value;
            string parameters = String.Empty;
            if (match.Groups["p"].Success)
                parameters = match.Groups["p"].Value;
            #endregion

            #region 创建函数
            Function function = new Function();
            function.Name = name;
            function.Params = new List<object>();
            #endregion

            #region 分析参数
            if (!String.IsNullOrEmpty(parameters))
            {
                string param = String.Empty;
                Stack<char> opened = new Stack<char>();
                for (int i = 0; i <= parameters.Length; i++)
                {
                    if (i == parameters.Length || parameters[i] == ',' && opened.Count == 0)
                    {
                        if (String.IsNullOrEmpty(param))
                            continue;

                        if (Regex.IsMatch(param, @"^(?<n>[a-z0-9_]+)\((?<p>.*?)\)$", RegexOptions.IgnoreCase))
                            function.Params.Add(ParseFunction(param));
                        else
                            function.Params.Add(param.Trim());

                        param = String.Empty;
                        continue;
                    }
                    else if (parameters[i] == '\'' && !(i > 0 && parameters[i - 1] == '\\'))
                    {
                        if (opened.Count > 0 && opened.Peek() == '\'')
                            opened.Pop();
                        else
                            opened.Push('\'');
                    }
                    else if (parameters[i] == '/' && (i > 0 && parameters[i - 1] == ','))
                    {
                        opened.Push('/');
                    }
                    else if (parameters[i] == '/' && (i + 1 < parameters.Length && parameters[i + 1] == ','))
                    {
                        if (opened.Count > 0 && opened.Peek() == '/')
                            opened.Pop();
                    }
                    else if (parameters[i] == '(' && (opened.Count == 0 || opened.Peek() != '\'' && opened.Peek() != '/'))
                    {
                        opened.Push('(');
                    }
                    else if (parameters[i] == ')')
                    {
                        //格式不正确
                        if (opened.Count == 0)
                            return null;

                        if (opened.Peek() == '(')
                            opened.Pop();
                    }

                    param += parameters[i];
                }
            }
            #endregion

            return function;
        }
        private class Function
        {
            public string Execute(Dictionary<string, object> state)
            {
                #region NewGuid
                if (Name == "NewGuid")
                {
                    return Guid.NewGuid().ToString();
                }
                #endregion
                #region ClearTag
                else if (Name == "ClearTag")
                {
                    string param = String.Empty;
                    if (Params.Count == 1)
                    {
                        if (Params[0] is Function)
                            param = ((Function)Params[0]).Execute(state);
                        else
                            param = GetVarValue(state, Params[0].ToString());
                    }
                    else if (state.ContainsKey("Input"))
                    {
                        param = state["Input"].ToString();
                    }

                    return Regex.Replace(param, @"(<style(.|\s)*?</style>)|(<script(.|\s)*?</script>)|(<!--(.|\s)*?-->)|(<[^>]*>)", "", RegexOptions.IgnoreCase);
                }
                #endregion
                #region Trim
                else if (Name == "Trim")
                {
                    string param = String.Empty;
                    if (Params.Count == 1)
                    {
                        if (Params[0] is Function)
                            param = ((Function)Params[0]).Execute(state);
                        else
                            param = GetVarValue(state, Params[0].ToString());
                    }
                    else if (state.ContainsKey("Input"))
                    {
                        param = state["Input"].ToString();
                    }

                    return param.Trim();
                }
                #endregion
                #region HtmlDecode
                else if (Name == "HtmlDecode")
                {
                    string param = String.Empty;
                    if (Params.Count == 1)
                    {
                        if (Params[0] is Function)
                            param = ((Function)Params[0]).Execute(state);
                        else
                            param = GetVarValue(state, Params[0].ToString());
                    }
                    else if (state.ContainsKey("Input"))
                    {
                        param = state["Input"].ToString();
                    }

                    return HttpUtility.HtmlDecode(param);
                }
                #endregion
                #region ClearWhiteSpace
                else if (Name == "ClearWhiteSpace")
                {
                    string param = String.Empty;
                    if (Params.Count == 1)
                    {
                        if (Params[0] is Function)
                            param = ((Function)Params[0]).Execute(state);
                        else
                            param = GetVarValue(state, Params[0].ToString());
                    }
                    else if (state.ContainsKey("Input"))
                    {
                        param = state["Input"].ToString();
                    }

                    return param.Replace("\n", "").Replace("\t", "").Replace(" ", "");
                }
                #endregion
                #region ToAbsUrl
                else if (Name == "ToAbsUrl")
                {
                    if (Params.Count == 0)
                    {
                        return "";
                    }
                    else if (Params.Count == 1)
                    {
                        if (Params[0] is Function)
                            return ((Function)Params[0]).Execute(state);
                        else
                            return Params[0].ToString();
                    }

                    #region Url
                    string url = String.Empty;
                    if (Params[0] is Function)
                    {
                        url = ((Function)Params[0]).Execute(state);
                    }
                    else
                    {
                        foreach (KeyValuePair<string, object> kvp in state)
                        {
                            if (!(kvp.Value is string))
                                continue;

                            if (kvp.Key.ToString() == Params[0].ToString())
                            {
                                url = kvp.Value.ToString();
                                break;
                            }
                        }

                        if (String.IsNullOrEmpty(url))
                            url = Params[0].ToString();
                    }
                    #endregion

                    #region Input
                    string input = String.Empty;
                    if (Params[1] is Function)
                    {
                        input = ((Function)Params[1]).Execute(state);
                    }
                    else
                    {
                        foreach (KeyValuePair<string, object> kvp in state)
                        {
                            if (!(kvp.Value is string))
                                continue;

                            if (kvp.Key.ToString() == Params[1].ToString())
                            {
                                input = kvp.Value.ToString();
                                break;
                            }
                        }

                        if (String.IsNullOrEmpty(input))
                            input = Params[1].ToString();
                    }
                    #endregion

                    if (String.IsNullOrEmpty(input))
                    {
                        return url;
                    }
                    else if (input.IndexOfAny(new char[] { '\r', '\n' }) != -1)
                    {
                        MatchCollection matches = Regex.Matches(input, @"\s+(href|src)=('|""|\s)?(?<v>.+?)('|""|>|\s)", RegexOptions.IgnoreCase);
                        for (int i = matches.Count - 1; i >= 0; i--)
                        {
                            input = input.Remove(matches[i].Groups["v"].Index, matches[i].Groups["v"].Length);
                            input = input.Insert(matches[i].Groups["v"].Index, ToAbsUrl(url, matches[i].Groups["v"].Value));
                        }
                        return input;
                    }
                    else
                    {
                        return ToAbsUrl(url, input);
                    }
                }
                #endregion
                #region Replace
                else if (Name == "Replace")
                {
                    if (!state.ContainsKey("Input"))
                        return String.Empty;
                    string input = state["Input"].ToString();

                    if (Params.Count != 3)
                        return input;

                    string param0 = String.Empty;
                    if (Params[0] is Function)
                        param0 = ((Function)Params[0]).Execute(state);
                    else
                        param0 = GetVarValue(state, Params[0].ToString());
                    if (String.IsNullOrEmpty(param0))
                        param0 = input;

                    string param1 = String.Empty;
                    if (Params[1] is Function)
                        param1 = ((Function)Params[1]).Execute(state);
                    else
                        param1 = GetVarValue(state, Params[1].ToString());

                    string param2 = String.Empty;
                    if (Params[2] is Function)
                        param2 = ((Function)Params[2]).Execute(state);
                    else
                        param2 = GetVarValue(state, Params[2].ToString());

                    if (param1.StartsWith("/") && param1.EndsWith("/"))
                        return Regex.Replace(param0, param1.Trim('/').Replace("\\/", "/"), param2, RegexOptions.IgnoreCase);
                    else
                        return param0.Replace(param1, param2);
                }
                #endregion
                #region 其他
                else
                {
                    #region javascript
                    XmlDocument doc = ((XmlNode)state["Rule"]).OwnerDocument;
                    XmlNode script = doc.SelectSingleNode("//Script");
                    if (script != null && script.InnerText.IndexOf("function " + Name + "(") != -1)
                    {
                        string evalClass = @"package JSEvaluator 
                        {
                            class JSEvaluator 
                            {
                                {Functions}
                            } 
                        }";

                        Microsoft.JScript.JScriptCodeProvider compiler = new Microsoft.JScript.JScriptCodeProvider();

                        CompilerParameters parameters;
                        parameters = new CompilerParameters();
                        parameters.GenerateInMemory = true;

                        CompilerResults results;
                        evalClass = evalClass.Replace("{Functions}", script.InnerText);
                        results = compiler.CompileAssemblyFromSource(parameters, evalClass);

                        Assembly assembly = results.CompiledAssembly;
                        Type type = assembly.GetType("JSEvaluator.JSEvaluator");

                        object evaluator = Activator.CreateInstance(type);

                        object[] objects = new object[Params.Count];
                        for (int i = 0; i < Params.Count; i++)
                        {
                            if (Params[i] is Function)
                                objects[i] = ((Function)Params[i]).Execute(state);
                            else
                                objects[i] = GetVarValue(state, Params[i].ToString());
                        }

                        return type.InvokeMember(Name, BindingFlags.InvokeMethod, null, evaluator, objects).ToString();
                    }
                    #endregion
                    else
                    {
                        if (state.ContainsKey("Input"))
                            return state["Input"].ToString();
                        else
                            return String.Empty;
                    }
                }
                #endregion
            }
            public static string GetVarValue(Dictionary<string, object> state, string key)
            {
                if (String.IsNullOrEmpty(key))
                    return key;

                if (key.StartsWith("'") && key.EndsWith("'") || key.StartsWith("\"") && key.EndsWith("\""))
                    return key.Trim(new char[] { ' ', '"', '\'' });

                if (key == "Input" && state.ContainsKey("Input"))
                    return state["Input"].ToString();

                if (key == "Url" && state.ContainsKey("Url"))
                    return state["Url"].ToString();

                if (state.ContainsKey("FieldNodes"))
                {
                    XmlNodeList fieldNodes = (XmlNodeList)state["FieldNodes"];
                    foreach (XmlNode fieldNode in fieldNodes)
                    {
                        if (key == fieldNode.Attributes["Name"].Value && fieldNode.Attributes["ParsedValue"] != null)
                            return fieldNode.Attributes["ParsedValue"].Value;
                    }
                }

                return key;
            }

            private string ToAbsUrl(string url, string input)
            {
                if (String.IsNullOrEmpty(input))
                {
                    return url;
                }
                else if (input.StartsWith("/"))
                {
                    Uri uri = new Uri(url);
                    return "http://" + uri.Host + input;
                }
                else if (input.StartsWith("../"))
                {
                    int index = url.LastIndexOf('/');
                    if (index == -1)
                        return input;

                    url = url.Substring(0, index);
                    while (input.StartsWith("../"))
                    {
                        input = input.Substring(3);

                        index = url.LastIndexOf('/');
                        if (index == -1)
                            return input;

                        url = url.Substring(0, index);
                    }

                    return url + "/" + input;
                }
                else if (input.StartsWith("?"))
                {
                    return url + input;
                }
                else
                {
                    if (input.StartsWith("./"))
                        input = input.Substring(2);

                    return url.Substring(0, url.LastIndexOf('/') + 1) + input;
                }
            }

            #region 属性
            public string Name = null;
            public List<Object> Params = null;
            #endregion
        }

        #region Fields
        private static Dictionary<int, ManualResetEvent> _runingRules;
        private static IManager _manager;
        #endregion

        #region Properties
        private Dal.IRule Dal
        {
            get { return (Dal.IRule)DalBase; }
        }
        #endregion
    }
}
